#pragma once
#include "Connection.hpp"
#include "Accept.hpp"
#include "LoopThreadPool.hpp"
#include <signal.h>

class TcpServer
{
private:
    uint64_t _next_id; // 这是一个自动增长的连接ID，
    int _port;
    int _timeout;                                       // 这是非活跃连接的统计时间---多长时间无通信就是非活跃连接
    bool _enable_inactive_release;                      // 是否启动了非活跃连接超时销毁的判断标志
    EventLoop _baseloop;                                // 这是主线程的EventLoop对象，负责监听事件的处理
    Acceptor _acceptor;                                 // 这是监听套接字的管理对象
    LoopThreadPool _pool;                               // 这是从属EventLoop线程池
    std::unordered_map<uint64_t, PtrConnection> _conns; // 保存管理所有连接对应的shared_ptr对象

    using ConnectedCallback = std::function<void(const PtrConnection &)>;
    using MessageCallback = std::function<void(const PtrConnection &, Buffer *)>;
    using ClosedCallback = std::function<void(const PtrConnection &)>;
    using AnyEventCallback = std::function<void(const PtrConnection &)>;
    using Functor = std::function<void()>;
    ConnectedCallback _connected_callback;
    MessageCallback _message_callback;
    ClosedCallback _closed_callback;
    AnyEventCallback _event_callback;

private:
    // 为新连接构造一个Connection进行管理
    void NewConnection(int fd)
    {
        _next_id++;
        PtrConnection conn(new Connection(_pool.NextLoop(), _next_id, fd));
        conn->SetMessageCallback(_message_callback);
        conn->SetClosedCallback(_closed_callback);
        conn->SetConnectedCallback(_connected_callback);
        conn->SetAnyEventCallback(_event_callback);
        conn->SetSrvClosedCallback(std::bind(&TcpServer::RemoveConnection, this, std::placeholders::_1));
        if (_enable_inactive_release)
            conn->EnableInactiveRelease(_timeout); // 启动非活跃超时销毁
        conn->Established();                       // 就绪初始化
        _conns.insert(std::make_pair(_next_id, conn));
    }
    // 从管理Connection的_conns中移除连接信息
    void RemoveConnectionInLoop(const PtrConnection &conn)
    {
        int id = conn->ConnectionID();
        auto it = _conns.find(id);
        if (it != _conns.end())
        {
            _conns.erase(it);
        }
    }

    void RemoveConnection(const PtrConnection &conn)
    {
        _baseloop.RunInLoop(std::bind(&TcpServer::RemoveConnectionInLoop, this, conn));
    }

    void SetTimeTaskInLoop(const Functor &task, int delay)
    {
        _next_id++;
        _baseloop.TimerAdd(_next_id, delay, task);
    }

public:
    TcpServer(int port) : _port(port), _next_id(0), _enable_inactive_release(false), 
    _acceptor(&_baseloop, port), _pool(&_baseloop)
    {
        _acceptor.SetAcceptCallback(std::bind(&TcpServer::NewConnection,this,std::placeholders::_1));
        _acceptor.Listen();
    }

    ~TcpServer() {}

    void SetThreadCount(int count) { _pool.SetThreadCount(count); }

    void SetConnectedCallback(const ConnectedCallback &cb) { _connected_callback = cb; }

    void SetMessageCallback(const MessageCallback &cb) { _message_callback = cb; }

    void SetClosedCallback(const ClosedCallback &cb) { _closed_callback = cb; }

    void SetAnyEventCallback(const AnyEventCallback &cb) { _event_callback = cb; }

    void EnableInactiveRelease(int sec)
    {
        _timeout = sec;
        _enable_inactive_release = true;
    }

    void SetTimeTask(const Functor &task, int delay)
    {
        _baseloop.RunInLoop(std::bind(&TcpServer::SetTimeTaskInLoop, this, task, delay));
    }

    void Start() {  _pool.Create(); _baseloop.Start(); }

    std::vector<uint64_t> GetEventLoopConnectCount(){
        return _pool.GetEventLoopConnectCount();
    }
};

class NetWork {
    public:
        NetWork() {
            log_message(DEBUG, "send fail信号已忽略");
            //避免因套接字关闭，send失败报错，导致的服务器关闭
            signal(SIGPIPE, SIG_IGN);
        }
};
static NetWork nw;